﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Threading;
using System.Windows;
using MicroIoc;
using Microsoft.Practices.Prism.Events;
using WeiboPlus.Common;
using WeiboPlus.Models;
using System.Collections;
using System.Windows.Media;
using WeiboPlus.Shell;
#if SINA
using WeiboPlus.Sina;
#endif
#if RENREN
using WeiboPlus.Renren;
#endif
#if TENCENT
using WeiboPlus.Tencent;
#endif
using WeiboPlus.Service;

namespace WeiboPlus
{
    public class PhoneApplicationController
    {
        private const string AccountSettings = "AccountSettings";
        private const string AppSettingKey = "AppSetting";
        public Dictionary<int, SNSAccount> AccountList;
        //private ISterlingDatabaseInstance _database = null;

        //public ISterlingDatabaseInstance Database
        //{
        //    get { return _database; }
        //}
        //private SterlingEngine _engine = null;
        //private SterlingDefaultLogger _logger = null;
        ApplicationSetting appSetting;
        public ApplicationSetting AppSetting
        {
            get
            {
                return appSetting;
            }
            set
            {
                if (appSetting != value)
                {
                    if (value != null)
                    {
                        if (appSetting != null)
                            appSetting.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(appSetting_PropertyChanged);
                        appSetting = value;
                        appSetting.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(appSetting_PropertyChanged);
                    }
                }
            }
        }

        void appSetting_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            ThreadPool.QueueUserWorkItem((o) =>
            {
                SaveAppSetting();
            }, null);
        }

        private static PhoneApplicationController controller;

        public static PhoneApplicationController Current
        {
            get
            {
                if (controller == null)
                    controller = new PhoneApplicationController();
                return controller;
            }
        }

        PhoneApplicationController()
        {
            Container = new MicroIocContainer();
        }

        IMicroIocContainer _container;
        public IMicroIocContainer Container
        {
            get { return _container; }
            set { _container = value; }
        }

        public void Run()
        {
            Initialize();
        }

        private void Initialize()
        {
            InitializeAccounts();

            RegisterDefaultService();

            InitializeSetting();

            ApplyLanguageSetting();

            ApplyTheme();
        }

        public static void ApplyLanguageSetting()
        {
            var name = Current.AppSetting.LanguageName;

            if (name != null)
            {
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(name);
            }
        }

        public static void ApplyTheme()
        {
            var path = Current.AppSetting.ThemeResourceDictionaryPath;

            if (!string.IsNullOrWhiteSpace(path))
            {
                var dic = new ResourceDictionary { Source = new Uri(path, UriKind.Relative) };
                Application.Current.Resources.MergedDictionaries.Add(dic);

                ResourceDictionary appResources = App.Current.Resources;
                foreach (DictionaryEntry entry in dic)
                {
                    SolidColorBrush colorBrush = entry.Value as SolidColorBrush;
                    SolidColorBrush existingBrush = appResources[entry.Key] as SolidColorBrush;
                    if (existingBrush != null && colorBrush != null)
                    {
                        existingBrush.Color = colorBrush.Color;
                    }
                }
            }
        }

        private void InitializeSetting()
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains(AppSettingKey))
            {
                AppSetting = IsolatedStorageSettings.ApplicationSettings[AppSettingKey] as ApplicationSetting;
                if (AppSetting == null)
                    AppSetting = ApplicationSetting.Default;
            }
            else
            {
                AppSetting = ApplicationSetting.Default;
                //IsolatedStorageSettings.ApplicationSettings.Add(AppSettingKey, AppSetting);
            }
        }

        private void InitializeAccounts()
        {
            AccountManager.Current.Load();

            AccountManager.Current.OnCreateNewAccount += new EventHandler<CreateNewAccountEventArgs>(Current_OnCreateNewAccount);
            AccountManager.Current.OnAccountRemoved += new EventHandler<AccountRemovedEventArgs>(Current_OnAccountRemoved);
        }

        void Current_OnAccountRemoved(object sender, AccountRemovedEventArgs e)
        {
            if (e.RemovedAccount == null || e.RemovedAccount.ServiceProvider == SNSProviderType.Unknow)
                return;

            var service = Container.Resolve<IStatusService>() as CompositeStatusService;
            if (service.Contains(e.RemovedAccount))
            {
                service.Remove(e.RemovedAccount);
            }
            //throw new NotImplementedException();
        }

        void Current_OnCreateNewAccount(object sender, CreateNewAccountEventArgs e)
        {
            //throw new NotImplementedException();
            if (e.NewAccount == null || e.NewAccount.ServiceProvider == SNSProviderType.Unknow)
                return;

            var account = e.NewAccount;
            var statusSvc = Container.Resolve<IStatusService>(account.ServiceProvider.ToString());

            statusSvc.ProviderResolver = () => SNSProviderManager.GetFactory(account).GetProvider();
            statusSvc.FactoryResolver = () => SNSProviderManager.CreateFactory(account);
            statusSvc.Account = account;

            var comStatusSvc = Container.Resolve<IStatusService>() as CompositeStatusService;
            if (comStatusSvc != null && !comStatusSvc.Contains(account))
                comStatusSvc.Register(account, statusSvc);


            IUserService userSvc = PhoneApplicationController.Current.Container.Resolve<IUserService>(account.ServiceProvider.ToString());

            userSvc.ProviderResolver = () => SNSProviderManager.GetFactory(account).GetProvider();
            userSvc.FactoryResolver = () => SNSProviderManager.CreateFactory(account);
            userSvc.Account = account;

            SNSRequest request = new SNSRequest() { Type = SNSType.CurrentUser };

            //renren

            userSvc.GetUser(request,
                (user, result) =>
                {
                    if (!result.IsSuccess)
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(() => { MessageBox.Show(result.Message); });
                        return;
                    }
                    if (AccountManager.Current.GetAllAccount().Any(item => item.UserLite != null && item.UserLite.AccountName == user.AccountName && item.UserLite.Id == user.Id))
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(() =>
                        {
                            var r = MessageBox.Show(AppResx.WarnOverrideAccountText, AppResx.WarnText, MessageBoxButton.OKCancel);
                            if (r == MessageBoxResult.OK)
                            {
                                account.IsDuplicate = true;
                                //AccountManager.Current.RemoveAccount(account);
                            }
                            PhoneApplicationController.Current.SaveSettings();
                        });
                    }
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        account.UserLite = user;
                    });

                    if (Deployment.Current != null && account.ServiceProvider != SNSProviderType.RenRen)
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(() =>
                        {
                            //userSvc.GetFriendship(SNSProviderManager.Current.GetProvider(account.ServiceProvider).SupportUser,(fr,re)=>
                            //{
                            //    if (!re.IsSuccess)
                            //    {
                            //        Deployment.Current.Dispatcher.BeginInvoke(() =>
                            //        {
                            //            MessageBox.Show(re.Message);
                            //        });
                            //    }
                            //    else
                            //    {
                            //        if (!fr.Source.Following)
                            //        {

                            //        }
                            //    }
                            //});
                            MessageBoxResult rs = MessageBox.Show(AppResx.FollowOfficialAccount, AppResx.BindNewAccountSuccess, MessageBoxButton.OKCancel);
                            if (rs == MessageBoxResult.OK)
                            {
                                userSvc.Follow(SNSProviderManager.Current.GetProvider(account.ServiceProvider).SupportUser, (u, re) =>
                                {
                                    if (!re.IsSuccess)
                                    {
                                        Deployment.Current.Dispatcher.BeginInvoke(() =>
                                        {
                                            MessageBox.Show(re.Message);
                                        });
                                    }
                                });
                            }
                        });
                    }
                    PhoneApplicationController.Current.SaveSettings();
                });
        }

        private void RegisterDefaultService()
        {
            Container.RegisterInstance<IAccountManager>(AccountManager.Current);
#if RENREN
            Container.Register<IOAuthService, RenrenOAuthService>(SNSProviderType.RenRen.ToString());
            Container.Register<IStatusService, RenrenStatusService>(SNSProviderType.RenRen.ToString());
            Container.Register<IUserService, RenrenUserService>(SNSProviderType.RenRen.ToString());
#endif
#if SINA
            Container.Register<IOAuthService, SinaOAuthService>(SNSProviderType.Sina.ToString());
            Container.Register<IStatusService, SinaStatusService>(SNSProviderType.Sina.ToString());
            Container.Register<IUserService, SinaUserService>(SNSProviderType.Sina.ToString());
#endif
#if TENCENT
            Container.Register<IOAuthService, TencentOAuthService>(SNSProviderType.Tencent.ToString());
            Container.Register<IStatusService, TencentStatusService>(SNSProviderType.Tencent.ToString());
            Container.Register<IUserService, TencentUserService>(SNSProviderType.Tencent.ToString());
#endif
            var comStatusSvc = new CompositeStatusService();

            foreach (var account in AccountManager.Current.GetAllAccount())
            {
                if (account.ServiceProvider == SNSProviderType.Unknow || !account.IsBind)
                    continue;
                var service = Container.Resolve<IStatusService>(account.ServiceProvider.ToString());

                service.ProviderResolver = () => SNSProviderManager.GetFactory(account).GetProvider();
                service.FactoryResolver = () => SNSProviderManager.CreateFactory(account);
                service.Account = account;
                comStatusSvc.Register(account, service);
            }

            Container.RegisterInstance<IStatusService>(comStatusSvc);

            Container.RegisterInstance<IEventAggregator>(new EventAggregator());

            Container.Register<ISNSPollingService, SNSPollingService>();
        }

        public void SaveSettings()
        {
            AccountManager.Current.Remove((account) => { return !account.IsBind || account.IsDuplicate; });
            AccountManager.Current.Save();

            SaveAppSetting();
        }

        private void SaveAppSetting()
        {
            if (IsolatedStorageSettings.ApplicationSettings.Contains(AppSettingKey))
            {
                IsolatedStorageSettings.ApplicationSettings[AppSettingKey] = AppSetting;
            }
            else
            {
                IsolatedStorageSettings.ApplicationSettings.Add(AppSettingKey, AppSetting);
            }
        }

        //public void ActivateDBEngine()
        //{
        //    _engine = new SterlingEngine();
        //    _logger = new SterlingDefaultLogger(SterlingLogLevel.Information);
        //    _engine.Activate();
        //    _database = _engine.SterlingDatabase.RegisterDatabase<StatusDatabase>();
        //    //var maxIdx =
        //    //    _database.Query<ItemViewModel, int>().Any() ?
        //    //    (from id in _database.Query<ItemViewModel, int>()
        //    //     select id.Key).Max() + 1 : 1;
        //    //_database.RegisterTrigger<ItemViewModel, int>(new WindowsPhoneSterling.Sterling.ItemDatabase.ItemTrigger(maxIdx));

        //}

        //public void DeactivateDBEngine()
        //{
        //    _logger.Detach();
        //    _engine.Dispose();
        //    _database = null;
        //    _engine = null;
        //}
    }
}

